{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MLFlow Model Server\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Clone MLflow repo so we get access to the examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cloning into 'mlflow'...\n",
      "remote: Enumerating objects: 1, done.\u001b[K\n",
      "remote: Counting objects: 100% (1/1), done.\u001b[K\n",
      "remote: Total 11829 (delta 0), reused 0 (delta 0), pack-reused 11828\u001b[K\n",
      "Receiving objects: 100% (11829/11829), 9.69 MiB | 1.17 MiB/s, done.\n",
      "Resolving deltas: 100% (7778/7778), done.\n"
     ]
    }
   ],
   "source": [
    "!git clone https://github.com/mlflow/mlflow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run the sklearn elasticnet wine example so we generate some mlflow models, which we can then load"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Elasticnet model (alpha=0.500000, l1_ratio=0.500000):\r\n",
      "  RMSE: 0.8222428497595403\r\n",
      "  MAE: 0.6278761410160693\r\n",
      "  R2: 0.12678721972772622\r\n"
     ]
    }
   ],
   "source": [
    "!python mlflow/examples/sklearn_elasticnet_wine/train.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test locally"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append(\"..\")\n",
    "from mlflowserver.MLFlowServer import MLFlowServer\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = MLFlowServer(\"mlruns/0/\"+next(os.walk('mlruns/0'))[1][0]+\"/artifacts/model\")\n",
    "m.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([6.24456105])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.predict([[1,2,3,4,5,6,7,8,9,10,11]], feature_names=[])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## REST test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s2i build -E environment_rest ./mlflowserver seldonio/seldon-core-s2i-python37:0.11-SNAPSHOT seldonio/mlflowserver_rest:0.1\n",
      "---> Installing application source...\n",
      "---> Installing dependencies ...\n",
      "Looking in links: /whl\n",
      "Collecting mlflow (from -r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ae/d2/b597d667cd809851cc90d4b06dfbc43b4f2787a782575086409574dc0acd/mlflow-1.1.0-py3-none-any.whl (26.2MB)\n",
      "Collecting sklearn (from -r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/1e/7a/dbb3be0ce9bd5c8b7e3d87328e79063f8b263b2b1bfa4774cb1147bfcd3f/sklearn-0.0.tar.gz\n",
      "Collecting pandas (from -r requirements.txt (line 3))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/3b/42/dc1f4820b95fbdbc9352ec9ad0f0c40db2122e1f2440ea53c7f9fbccf2b8/pandas-0.25.0-cp37-cp37m-manylinux1_x86_64.whl (10.4MB)\n",
      "Collecting alembic (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/7b/8b/0c98c378d93165d9809193f274c3c6e2151120d955b752419c7d43e4d857/alembic-1.0.11.tar.gz (1.0MB)\n",
      "Collecting docker>=3.6.0 (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/95/47/5560c9cf0c92b50da24216f0e7733250fbed5a497f69e3c70e1be62143fe/docker-4.0.2-py2.py3-none-any.whl (138kB)\n",
      "Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (5.1.1)\n",
      "Collecting cloudpickle (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/09/f4/4a080c349c1680a2086196fcf0286a65931708156f39568ed7051e42ff6a/cloudpickle-1.2.1-py2.py3-none-any.whl\n",
      "Collecting gunicorn (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl (112kB)\n",
      "Collecting simplejson (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/e3/24/c35fb1c1c315fc0fffe61ea00d3f88e85469004713dab488dee4f35b0aff/simplejson-3.16.0.tar.gz (81kB)\n",
      "Collecting entrypoints (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ac/c6/44694103f8c221443ee6b0041f69e2740d89a25641e62fb4f2ee568f2f9c/entrypoints-0.3-py2.py3-none-any.whl\n",
      "Requirement already satisfied: click>=7.0 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (7.0)\n",
      "Collecting querystring-parser (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/4a/fa/f54f5662e0eababf0c49e92fd94bf178888562c0e7b677c8941bbbcd1bd6/querystring_parser-1.2.4.tar.gz\n",
      "Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (1.12.0)\n",
      "Requirement already satisfied: requests>=2.17.3 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (2.22.0)\n",
      "Requirement already satisfied: Flask in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (1.1.1)\n",
      "Requirement already satisfied: protobuf>=3.6.0 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (3.9.0)\n",
      "Collecting sqlalchemy (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/55/98/56b7155bab287cd0c78dee26258835db36e91f2efef41f125ed6f6f1f334/SQLAlchemy-1.3.6.tar.gz (5.9MB)\n",
      "Collecting gorilla (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/e3/56/5a683944cbfc77e429c6f03c636ca50504a785f60ffae91ddd7f5f7bb520/gorilla-0.3.0-py2.py3-none-any.whl\n",
      "Collecting databricks-cli>=0.8.7 (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/5f/38/f83bc71c5e7351a03e8d44aaf04647d076bbf8f097e3f93b921704b7a74c/databricks_cli-0.8.7-py3-none-any.whl (82kB)\n",
      "Requirement already satisfied: numpy in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (1.16.4)\n",
      "Collecting sqlparse (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ef/53/900f7d2a54557c6a37886585a91336520e5539e3ae2423ff1102daf4f3a7/sqlparse-0.3.0-py2.py3-none-any.whl\n",
      "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (2.8.0)\n",
      "Collecting gitpython>=2.1.0 (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/3c/d3/aecfe42163233de6071248ea7565e97ba1c51e345a9e1dcc128dd1e46c1e/GitPython-2.1.13-py2.py3-none-any.whl (452kB)\n",
      "Collecting scikit-learn (from sklearn->-r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/9f/c5/e5267eb84994e9a92a2c6a6ee768514f255d036f3c8378acfa694e9f2c99/scikit_learn-0.21.3-cp37-cp37m-manylinux1_x86_64.whl (6.7MB)\n",
      "Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/site-packages (from pandas->-r requirements.txt (line 3)) (2019.1)\n",
      "Collecting Mako (from alembic->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/b0/3c/8dcd6883d009f7cae0f3157fb53e9afb05a0d3d33b3db1268ec2e6f4a56b/Mako-1.1.0.tar.gz (463kB)\n",
      "Collecting python-editor>=0.3 (from alembic->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/c6/d3/201fc3abe391bbae6606e6f1d598c15d367033332bd54352b12f35513717/python_editor-1.0.4-py3-none-any.whl\n",
      "Collecting websocket-client>=0.32.0 (from docker>=3.6.0->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/29/19/44753eab1fdb50770ac69605527e8859468f3c0fd7dc5a76dd9c4dbd7906/websocket_client-0.56.0-py2.py3-none-any.whl (200kB)\n",
      "Requirement already satisfied: idna<2.9,>=2.5 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (2.8)\n",
      "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (1.25.3)\n",
      "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (3.0.4)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (2019.6.16)\n",
      "Requirement already satisfied: Werkzeug>=0.15 in /usr/local/lib/python3.7/site-packages (from Flask->mlflow->-r requirements.txt (line 1)) (0.15.5)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: Jinja2>=2.10.1 in /usr/local/lib/python3.7/site-packages (from Flask->mlflow->-r requirements.txt (line 1)) (2.10.1)\n",
      "Requirement already satisfied: itsdangerous>=0.24 in /usr/local/lib/python3.7/site-packages (from Flask->mlflow->-r requirements.txt (line 1)) (1.1.0)\n",
      "Requirement already satisfied: setuptools in /usr/local/lib/python3.7/site-packages (from protobuf>=3.6.0->mlflow->-r requirements.txt (line 1)) (41.0.1)\n",
      "Collecting tabulate>=0.7.7 (from databricks-cli>=0.8.7->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/c2/fd/202954b3f0eb896c53b7b6f07390851b1fd2ca84aa95880d7ae4f434c4ac/tabulate-0.8.3.tar.gz (46kB)\n",
      "Collecting configparser>=0.3.5 (from databricks-cli>=0.8.7->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ba/05/6c96328e92e625fc31445d24d75a2c92ef9ba34fc5b037fe69693c362a0d/configparser-3.7.4-py2.py3-none-any.whl\n",
      "Collecting gitdb2>=2.0.0 (from gitpython>=2.1.0->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/da/30/a407568aa8d8f25db817cf50121a958722f3fc5f87e3a6fba1f40c0633e3/gitdb2-2.0.5-py2.py3-none-any.whl (62kB)\n",
      "Collecting joblib>=0.11 (from scikit-learn->sklearn->-r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/cd/c1/50a758e8247561e58cb87305b1e90b171b8c767b15b12a1734001f41d356/joblib-0.13.2-py2.py3-none-any.whl (278kB)\n",
      "Collecting scipy>=0.17.0 (from scikit-learn->sklearn->-r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/94/7f/b535ec711cbcc3246abea4385d17e1b325d4c3404dd86f15fc4f3dba1dbb/scipy-1.3.1-cp37-cp37m-manylinux1_x86_64.whl (25.2MB)\n",
      "Requirement already satisfied: MarkupSafe>=0.9.2 in /usr/local/lib/python3.7/site-packages (from Mako->alembic->mlflow->-r requirements.txt (line 1)) (1.1.1)\n",
      "Collecting smmap2>=2.0.0 (from gitdb2>=2.0.0->gitpython>=2.1.0->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/55/d2/866d45e3a121ee15a1dc013824d58072fd5c7799c9c34d01378eb262ca8f/smmap2-2.0.5-py2.py3-none-any.whl\n",
      "Building wheels for collected packages: sklearn, alembic, simplejson, querystring-parser, sqlalchemy, Mako, tabulate\n",
      "Building wheel for sklearn (setup.py): started\n",
      "Building wheel for sklearn (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/76/03/bb/589d421d27431bcd2c6da284d5f2286c8e3b2ea3cf1594c074\n",
      "Building wheel for alembic (setup.py): started\n",
      "Building wheel for alembic (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/8b/65/b2/9837b4422d13e739c3324c428f1b3aa9e3c3df666bb420e4b3\n",
      "Building wheel for simplejson (setup.py): started\n",
      "Building wheel for simplejson (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/5d/1a/1e/0350bb3df3e74215cd91325344cc86c2c691f5306eb4d22c77\n",
      "Building wheel for querystring-parser (setup.py): started\n",
      "Building wheel for querystring-parser (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/1e/41/34/23ebf5d1089a9aed847951e0ee375426eb4ad0a7079d88d41e\n",
      "Building wheel for sqlalchemy (setup.py): started\n",
      "Building wheel for sqlalchemy (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/f2/ec/e0/d7deb0c981557e373edf7370574b7001690892afe5fea30c3c\n",
      "Building wheel for Mako (setup.py): started\n",
      "Building wheel for Mako (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/98/32/7b/a291926643fc1d1e02593e0d9e247c5a866a366b8343b7aa27\n",
      "Building wheel for tabulate (setup.py): started\n",
      "Building wheel for tabulate (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/2b/67/89/414471314a2d15de625d184d8be6d38a03ae1e983dbda91e84\n",
      "Successfully built sklearn alembic simplejson querystring-parser sqlalchemy Mako tabulate\n",
      "Installing collected packages: sqlalchemy, Mako, python-editor, alembic, websocket-client, docker, pandas, cloudpickle, gunicorn, simplejson, entrypoints, querystring-parser, gorilla, tabulate, configparser, databricks-cli, sqlparse, smmap2, gitdb2, gitpython, mlflow, joblib, scipy, scikit-learn, sklearn\n",
      "Successfully installed Mako-1.1.0 alembic-1.0.11 cloudpickle-1.2.1 configparser-3.7.4 databricks-cli-0.8.7 docker-4.0.2 entrypoints-0.3 gitdb2-2.0.5 gitpython-2.1.13 gorilla-0.3.0 gunicorn-19.9.0 joblib-0.13.2 mlflow-1.1.0 pandas-0.25.0 python-editor-1.0.4 querystring-parser-1.2.4 scikit-learn-0.21.3 scipy-1.3.1 simplejson-3.16.0 sklearn-0.0 smmap2-2.0.5 sqlalchemy-1.3.6 sqlparse-0.3.0 tabulate-0.8.3 websocket-client-0.56.0\n",
      "WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "WARNING: You are using pip version 19.1.1, however version 19.2.1 is available.\n",
      "You should consider upgrading via the 'pip install --upgrade pip' command.\n",
      "Build completed successfully\n"
     ]
    }
   ],
   "source": [
    "!cd .. && make build_rest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mlruns/0/640ee112155e46e682b35b2768ae7f4d/artifacts/model\n"
     ]
    }
   ],
   "source": [
    "print(\"mlruns/0/\"+next(os.walk(\"mlruns/0\"))[1][0]+\"/artifacts/model\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mlruns/0/640ee112155e46e682b35b2768ae7f4d/artifacts/model\r\n"
     ]
    }
   ],
   "source": [
    "!echo `python -c 'import os; print(\"mlruns/0/\"+next(os.walk(\"mlruns/0\"))[1][0]+\"/artifacts/model\")'`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mlflowserver\r\n"
     ]
    }
   ],
   "source": [
    "!docker rm -f \"mlflowserver\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6b66cf04d948d78f8b856f8de792201a0d08a11bfdf5e67d1749f5255eb383e0\r\n"
     ]
    }
   ],
   "source": [
    "!docker run --rm -d --name \"mlflowserver\"  -p 5000:5000 -e PREDICTIVE_UNIT_PARAMETERS='[{\"type\":\"STRING\",\"name\":\"model_uri\",\"value\":\"file:///model\"}]' -v `pwd`/`python -c 'import os; print(\"mlruns/0/\"+next(os.walk(\"mlruns/0\"))[1][0]+\"/artifacts/model\")'`:/model seldonio/mlflowserver_rest:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Send some random features that conform to the contract"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------------------------------------\r\n",
      "SENDING NEW REQUEST:\r\n",
      "\r\n",
      "[[6.666 3.774 0.138 0.858 2.137 1.385 2.822 1.194 0.228 1.692 1.228]]\r\n",
      "RECEIVED RESPONSE:\r\n",
      "meta {\r\n",
      "}\r\n",
      "data {\r\n",
      "  ndarray {\r\n",
      "    values {\r\n",
      "      number_value: 5.285221887024144\r\n",
      "    }\r\n",
      "  }\r\n",
      "}\r\n",
      "\r\n",
      "\r\n"
     ]
    }
   ],
   "source": [
    "!seldon-core-tester contract.json 0.0.0.0 5000 -p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mlflowserver\r\n"
     ]
    }
   ],
   "source": [
    "!docker rm mlflowserver --force"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## grpc test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s2i build -E environment_grpc ./mlflowserver seldonio/seldon-core-s2i-python37:0.11-SNAPSHOT seldonio/mlflowserver_grpc:0.1\n",
      "---> Installing application source...\n",
      "---> Installing dependencies ...\n",
      "Looking in links: /whl\n",
      "Collecting mlflow (from -r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ae/d2/b597d667cd809851cc90d4b06dfbc43b4f2787a782575086409574dc0acd/mlflow-1.1.0-py3-none-any.whl (26.2MB)\n",
      "Collecting sklearn (from -r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/1e/7a/dbb3be0ce9bd5c8b7e3d87328e79063f8b263b2b1bfa4774cb1147bfcd3f/sklearn-0.0.tar.gz\n",
      "Collecting pandas (from -r requirements.txt (line 3))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/3b/42/dc1f4820b95fbdbc9352ec9ad0f0c40db2122e1f2440ea53c7f9fbccf2b8/pandas-0.25.0-cp37-cp37m-manylinux1_x86_64.whl (10.4MB)\n",
      "Requirement already satisfied: click>=7.0 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (7.0)\n",
      "Collecting gunicorn (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl (112kB)\n",
      "Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (1.12.0)\n",
      "Collecting databricks-cli>=0.8.7 (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/5f/38/f83bc71c5e7351a03e8d44aaf04647d076bbf8f097e3f93b921704b7a74c/databricks_cli-0.8.7-py3-none-any.whl (82kB)\n",
      "Collecting entrypoints (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ac/c6/44694103f8c221443ee6b0041f69e2740d89a25641e62fb4f2ee568f2f9c/entrypoints-0.3-py2.py3-none-any.whl\n",
      "Collecting sqlparse (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ef/53/900f7d2a54557c6a37886585a91336520e5539e3ae2423ff1102daf4f3a7/sqlparse-0.3.0-py2.py3-none-any.whl\n",
      "Collecting gitpython>=2.1.0 (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/3c/d3/aecfe42163233de6071248ea7565e97ba1c51e345a9e1dcc128dd1e46c1e/GitPython-2.1.13-py2.py3-none-any.whl (452kB)\n",
      "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (2.8.0)\n",
      "Requirement already satisfied: protobuf>=3.6.0 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (3.9.0)\n",
      "Collecting simplejson (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/e3/24/c35fb1c1c315fc0fffe61ea00d3f88e85469004713dab488dee4f35b0aff/simplejson-3.16.0.tar.gz (81kB)\n",
      "Collecting docker>=3.6.0 (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/95/47/5560c9cf0c92b50da24216f0e7733250fbed5a497f69e3c70e1be62143fe/docker-4.0.2-py2.py3-none-any.whl (138kB)\n",
      "Collecting alembic (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/7b/8b/0c98c378d93165d9809193f274c3c6e2151120d955b752419c7d43e4d857/alembic-1.0.11.tar.gz (1.0MB)\n",
      "Requirement already satisfied: requests>=2.17.3 in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (2.22.0)\n",
      "Collecting sqlalchemy (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/55/98/56b7155bab287cd0c78dee26258835db36e91f2efef41f125ed6f6f1f334/SQLAlchemy-1.3.6.tar.gz (5.9MB)\n",
      "Collecting cloudpickle (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/09/f4/4a080c349c1680a2086196fcf0286a65931708156f39568ed7051e42ff6a/cloudpickle-1.2.1-py2.py3-none-any.whl\n",
      "Requirement already satisfied: Flask in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (1.1.1)\n",
      "Collecting querystring-parser (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/4a/fa/f54f5662e0eababf0c49e92fd94bf178888562c0e7b677c8941bbbcd1bd6/querystring_parser-1.2.4.tar.gz\n",
      "Collecting gorilla (from mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/e3/56/5a683944cbfc77e429c6f03c636ca50504a785f60ffae91ddd7f5f7bb520/gorilla-0.3.0-py2.py3-none-any.whl\n",
      "Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (5.1.1)\n",
      "Requirement already satisfied: numpy in /usr/local/lib/python3.7/site-packages (from mlflow->-r requirements.txt (line 1)) (1.16.4)\n",
      "Collecting scikit-learn (from sklearn->-r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/9f/c5/e5267eb84994e9a92a2c6a6ee768514f255d036f3c8378acfa694e9f2c99/scikit_learn-0.21.3-cp37-cp37m-manylinux1_x86_64.whl (6.7MB)\n",
      "Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/site-packages (from pandas->-r requirements.txt (line 3)) (2019.1)\n",
      "Collecting tabulate>=0.7.7 (from databricks-cli>=0.8.7->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/c2/fd/202954b3f0eb896c53b7b6f07390851b1fd2ca84aa95880d7ae4f434c4ac/tabulate-0.8.3.tar.gz (46kB)\n",
      "Collecting configparser>=0.3.5 (from databricks-cli>=0.8.7->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/ba/05/6c96328e92e625fc31445d24d75a2c92ef9ba34fc5b037fe69693c362a0d/configparser-3.7.4-py2.py3-none-any.whl\n",
      "Collecting gitdb2>=2.0.0 (from gitpython>=2.1.0->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/da/30/a407568aa8d8f25db817cf50121a958722f3fc5f87e3a6fba1f40c0633e3/gitdb2-2.0.5-py2.py3-none-any.whl (62kB)\n",
      "Requirement already satisfied: setuptools in /usr/local/lib/python3.7/site-packages (from protobuf>=3.6.0->mlflow->-r requirements.txt (line 1)) (41.0.1)\n",
      "Collecting websocket-client>=0.32.0 (from docker>=3.6.0->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/29/19/44753eab1fdb50770ac69605527e8859468f3c0fd7dc5a76dd9c4dbd7906/websocket_client-0.56.0-py2.py3-none-any.whl (200kB)\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Collecting Mako (from alembic->mlflow->-r requirements.txt (line 1))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading https://files.pythonhosted.org/packages/b0/3c/8dcd6883d009f7cae0f3157fb53e9afb05a0d3d33b3db1268ec2e6f4a56b/Mako-1.1.0.tar.gz (463kB)\n",
      "Collecting python-editor>=0.3 (from alembic->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/c6/d3/201fc3abe391bbae6606e6f1d598c15d367033332bd54352b12f35513717/python_editor-1.0.4-py3-none-any.whl\n",
      "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (3.0.4)\n",
      "Requirement already satisfied: idna<2.9,>=2.5 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (2.8)\n",
      "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (1.25.3)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/site-packages (from requests>=2.17.3->mlflow->-r requirements.txt (line 1)) (2019.6.16)\n",
      "Requirement already satisfied: Jinja2>=2.10.1 in /usr/local/lib/python3.7/site-packages (from Flask->mlflow->-r requirements.txt (line 1)) (2.10.1)\n",
      "Requirement already satisfied: Werkzeug>=0.15 in /usr/local/lib/python3.7/site-packages (from Flask->mlflow->-r requirements.txt (line 1)) (0.15.5)\n",
      "Requirement already satisfied: itsdangerous>=0.24 in /usr/local/lib/python3.7/site-packages (from Flask->mlflow->-r requirements.txt (line 1)) (1.1.0)\n",
      "Collecting joblib>=0.11 (from scikit-learn->sklearn->-r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/cd/c1/50a758e8247561e58cb87305b1e90b171b8c767b15b12a1734001f41d356/joblib-0.13.2-py2.py3-none-any.whl (278kB)\n",
      "Collecting scipy>=0.17.0 (from scikit-learn->sklearn->-r requirements.txt (line 2))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/94/7f/b535ec711cbcc3246abea4385d17e1b325d4c3404dd86f15fc4f3dba1dbb/scipy-1.3.1-cp37-cp37m-manylinux1_x86_64.whl (25.2MB)\n",
      "Collecting smmap2>=2.0.0 (from gitdb2>=2.0.0->gitpython>=2.1.0->mlflow->-r requirements.txt (line 1))\n",
      "  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "Downloading https://files.pythonhosted.org/packages/55/d2/866d45e3a121ee15a1dc013824d58072fd5c7799c9c34d01378eb262ca8f/smmap2-2.0.5-py2.py3-none-any.whl\n",
      "Requirement already satisfied: MarkupSafe>=0.9.2 in /usr/local/lib/python3.7/site-packages (from Mako->alembic->mlflow->-r requirements.txt (line 1)) (1.1.1)\n",
      "Building wheels for collected packages: sklearn, simplejson, alembic, sqlalchemy, querystring-parser, tabulate, Mako\n",
      "Building wheel for sklearn (setup.py): started\n",
      "Building wheel for sklearn (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/76/03/bb/589d421d27431bcd2c6da284d5f2286c8e3b2ea3cf1594c074\n",
      "Building wheel for simplejson (setup.py): started\n",
      "Building wheel for simplejson (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/5d/1a/1e/0350bb3df3e74215cd91325344cc86c2c691f5306eb4d22c77\n",
      "Building wheel for alembic (setup.py): started\n",
      "Building wheel for alembic (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/8b/65/b2/9837b4422d13e739c3324c428f1b3aa9e3c3df666bb420e4b3\n",
      "Building wheel for sqlalchemy (setup.py): started\n",
      "Building wheel for sqlalchemy (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/f2/ec/e0/d7deb0c981557e373edf7370574b7001690892afe5fea30c3c\n",
      "Building wheel for querystring-parser (setup.py): started\n",
      "Building wheel for querystring-parser (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/1e/41/34/23ebf5d1089a9aed847951e0ee375426eb4ad0a7079d88d41e\n",
      "Building wheel for tabulate (setup.py): started\n",
      "Building wheel for tabulate (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/2b/67/89/414471314a2d15de625d184d8be6d38a03ae1e983dbda91e84\n",
      "Building wheel for Mako (setup.py): started\n",
      "Building wheel for Mako (setup.py): finished with status 'done'\n",
      "Stored in directory: /root/.cache/pip/wheels/98/32/7b/a291926643fc1d1e02593e0d9e247c5a866a366b8343b7aa27\n",
      "Successfully built sklearn simplejson alembic sqlalchemy querystring-parser tabulate Mako\n",
      "Installing collected packages: gunicorn, tabulate, configparser, databricks-cli, entrypoints, sqlparse, smmap2, gitdb2, gitpython, simplejson, websocket-client, docker, sqlalchemy, Mako, python-editor, alembic, cloudpickle, querystring-parser, gorilla, pandas, mlflow, joblib, scipy, scikit-learn, sklearn\n",
      "Successfully installed Mako-1.1.0 alembic-1.0.11 cloudpickle-1.2.1 configparser-3.7.4 databricks-cli-0.8.7 docker-4.0.2 entrypoints-0.3 gitdb2-2.0.5 gitpython-2.1.13 gorilla-0.3.0 gunicorn-19.9.0 joblib-0.13.2 mlflow-1.1.0 pandas-0.25.0 python-editor-1.0.4 querystring-parser-1.2.4 scikit-learn-0.21.3 scipy-1.3.1 simplejson-3.16.0 sklearn-0.0 smmap2-2.0.5 sqlalchemy-1.3.6 sqlparse-0.3.0 tabulate-0.8.3 websocket-client-0.56.0\n",
      "WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.\n",
      "WARNING: You are using pip version 19.1.1, however version 19.2.1 is available.\n",
      "You should consider upgrading via the 'pip install --upgrade pip' command.\n",
      "Build completed successfully\n"
     ]
    }
   ],
   "source": [
    "!cd .. && make build_grpc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mlflowserver\r\n"
     ]
    }
   ],
   "source": [
    "!docker rm -f \"mlflowserver\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cbfcb010d313d3ebb74a34933fa05b2ab7cbbfe43934a47e6c9fd4f7c08c64e6\r\n"
     ]
    }
   ],
   "source": [
    "!docker run --rm -d --name \"mlflowserver\"  -p 5000:5000 -e PREDICTIVE_UNIT_PARAMETERS='[{\"type\":\"STRING\",\"name\":\"model_uri\",\"value\":\"file:///model\"}]' -v `pwd`/`python -c 'import os; print(\"mlruns/0/\"+next(os.walk(\"mlruns/0\"))[1][0]+\"/artifacts/model\")'`:/model seldonio/mlflowserver_grpc:0.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Test using NDArray payload"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------------------------------------\r\n",
      "SENDING NEW REQUEST:\r\n",
      "\r\n",
      "[[7.51  8.353 2.899 1.155 0.458 1.462 2.619 0.378 1.856 1.969 1.361]]\r\n",
      "RECEIVED RESPONSE:\r\n",
      "None\r\n",
      "\r\n"
     ]
    }
   ],
   "source": [
    "!seldon-core-tester contract.json 0.0.0.0 5000 -p --grpc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Test using Tensor payload"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------------------------------------\r\n",
      "SENDING NEW REQUEST:\r\n",
      "\r\n",
      "[[7.522 4.718 2.436 0.608 1.946 2.264 2.842 2.468 1.831 0.618 0.01 ]]\r\n",
      "RECEIVED RESPONSE:\r\n",
      "None\r\n",
      "\r\n"
     ]
    }
   ],
   "source": [
    "!seldon-core-tester contract.json 0.0.0.0 5000 -p --grpc --tensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sklearnserver\r\n"
     ]
    }
   ],
   "source": [
    "!docker rm sklearnserver --force"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
